package com.liting.uitest.imgutils;

import com.liting.uitest.model.Circle;
import com.liting.uitest.model.GrayImagePixel;
import com.liting.uitest.model.ImagePixel;
import com.liting.uitest.model.Rectangle;
import org.opencv.core.*;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.opencv.core.CvType.CV_8U;

public class OpenCVImageUtils {

    static {
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static Mat getGrapMat(Mat colorImage) {
        Mat grayImage = new Mat();
        Imgproc.cvtColor(colorImage, grayImage, Imgproc.COLOR_BGR2GRAY);
        return grayImage;
    }

    public static GrayImagePixel getGrayPixelByCoord(String imagFile, int x, int y) {
        // 加载图像
        Mat colorImage = Imgcodecs.imread(imagFile);

        // 检查图像是否读取成功
        if (colorImage.empty()) {
            System.out.println("Error: Could not read the image.");
            return null;
        } else {
            // 将彩色图像转换为灰度图像
            Mat grayImage = new Mat();
            if (colorImage.depth() != CV_8U) {
                Mat converted = new Mat();
                Core.convertScaleAbs(colorImage, converted, 1, 0);
                Imgproc.cvtColor(converted, grayImage, Imgproc.COLOR_BGR2GRAY);
            } else {
                Imgproc.cvtColor(colorImage, grayImage, Imgproc.COLOR_BGR2GRAY);
            }

            // 获取图像的宽度和高度
            int width = grayImage.width();
            int height = grayImage.height();


            // 检查坐标是否在图像范围内
            if (x < width && y < height) {
                // 获取单个像素的灰度值
                double[] grayValue = grayImage.get(y, x);

                System.out.print(Arrays.toString(grayValue));

                GrayImagePixel grayImagePixel = new GrayImagePixel(x, y, (int) grayValue[0]);

                // 注意：get()返回一个double数组，但在这里我们只需要一个元素，因为是灰度图像
                //System.out.println("Pixel at (" + x + ", " + y + ") has a grayscale value of: " + (int) grayValue);

                return grayImagePixel;
            } else {
                return null;
            }


        }
    }

    public static Double getGrayPixelByCoord(Mat grayImage, int x, int y) {


        // 检查图像是否读取成功
        if (grayImage.empty()) {
            System.out.println("Error: Could not read the image.");
            return null;
        } else {
            // 将彩色图像转换为灰度图像
//            Mat grayImage = new Mat();
//            Imgproc.cvtColor(colorImage, grayImage, Imgproc.COLOR_BGR2GRAY);

            // 获取图像的宽度和高度
            int width = grayImage.width();
            int height = grayImage.height();


            // 检查坐标是否在图像范围内
            if (x < width && y < height) {
                // 获取单个像素的灰度值
                double grayValue = grayImage.get(y, x)[0];

                return grayValue;

                //GrayImagePixel grayImagePixel=new GrayImagePixel(x,y,(int) grayValue);

                // 注意：get()返回一个double数组，但在这里我们只需要一个元素，因为是灰度图像
                //System.out.println("Pixel at (" + x + ", " + y + ") has a grayscale value of: " + (int) grayValue);

                //return grayImagePixel;
            } else {
                return null;
            }


        }
    }

    public static List<GrayImagePixel> getGrayPixelList(Mat colorImage) {
        // 检查图像是否读取成功
        if (colorImage.empty()) {
            System.out.println("Error: Could not read the image.");
            return null;
        } else {
            // 将彩色图像转换为灰度图像
            Mat grayImage = new Mat();
            Imgproc.cvtColor(colorImage, grayImage, Imgproc.COLOR_BGR2GRAY);

            // 获取图像的宽度和高度
            int width = grayImage.width();
            int height = grayImage.height();

            List<GrayImagePixel> grayImagePixelList = new ArrayList<>();

            // 如果要遍历整个图像并获取所有像素的灰度值
            for (int row = 0; row < height; row++) {
                for (int col = 0; col < width; col++) {
                    double[] pixelGray = grayImage.get(row, col);
                    int grayIntensity = (int) pixelGray[0];


                    GrayImagePixel grayImagePixel = new GrayImagePixel(col, row, grayIntensity);
                    grayImagePixelList.add(grayImagePixel);
                }
            }
            return grayImagePixelList;
        }

    }

    public static ImagePixel getPixelByCoord(String imagFile, int x, int y) {
        // 加载图像
        Mat image = Imgcodecs.imread(imagFile);

        System.out.println(image);

        // 检查图像是否读取成功
        if (image.empty()) {
            System.out.println("Error: Could not read the image.");
            return null;
        }

        // 获取图像的宽和高
        int width = image.width();
        int height = image.height();


        image.convertTo(image, CvType.CV_32S);
        //int size = (int) (image.total() * image.channels());
        int[] temp = new int[3];
//        image.get(0, 0, temp);
//
//        for (int i=0;i<image.rows();i++){//遍历行、列
//            for (int j=0;j<image.cols();j++){
//                image.get(i,j,temp);//获取每个运算，并存储在b数组中
//                System.out.print(Arrays.toString(temp));
//            }
//            System.out.println();
//        }


        // 检查坐标是否在图像范围内
        if (x < width && y < height) {


            image.get(y, x, temp);

            ImagePixel imagePixel = new ImagePixel(x, y, temp);

            return imagePixel;

            // BGR到RGB转换（如果需要显示或进一步处理为RGB格式）
//            int blue = (int) pixel[0];
//            int green = (int) pixel[1];
//            int red = (int) pixel[2];

        } else {
            return null;
        }
    }

    public static ImagePixel getPixelByCoord(Mat image, int x, int y) {


        // 获取图像的宽和高
        int width = image.width();
        int height = image.height();


        // 检查坐标是否在图像范围内
        if (x < width && y < height) {

            image.convertTo(image, CvType.CV_32S);
            //int size = (int) (image.total() * image.channels());
            int[] temp = new int[3];


            image.get(y, x, temp);

            ImagePixel imagePixel = new ImagePixel(x, y, temp);

            return imagePixel;

            // BGR到RGB转换（如果需要显示或进一步处理为RGB格式）
//            int blue = (int) pixel[0];
//            int green = (int) pixel[1];
//            int red = (int) pixel[2];

        } else {
            return null;
        }
    }

    public static Mat getRect(Mat src, Rectangle rectangle) {


        Range rowRange = new Range((int) rectangle.getLeftTopY(), (int) (rectangle.getLeftTopY() + rectangle.getHeight()));
        Range colRange = new Range((int) rectangle.getLeftTopX(), (int) (rectangle.getLeftTopX() + rectangle.getWidth()));
        Mat dst = src.submat(rowRange, colRange);

        Imgcodecs.imwrite("C:\\Users\\liting\\Pictures\\rect_cropped_image.jpg", dst);

        return dst;

    }

    public static Mat getCircle(Mat src, Circle circle) {


        // 假设我们知道圆形的位置（圆心坐标）和半径
        Point center = new Point(circle.getCenterX(), circle.getCenterY()); // 示例：圆心位于图片中心
        Double radius = circle.getRadius(); // 示例半径

        // 2. 创建掩码
        Mat mask = Mat.zeros(src.size(), CvType.CV_8UC1); // 全黑图片
        Imgproc.circle(mask, center, radius.intValue(), new Scalar(255), -1); // 绘制白色圆形，-1表示填充


        // 3. 应用掩码到原图片
        Mat dst = new Mat();
        Core.bitwise_and(src, src, dst, mask); // 只保留圆形部分

        // 4. 保存或显示结果
        //Imgcodecs.imwrite("C:\\Users\\liting\\Pictures\\circle_cropped_image.jpg", dst);
        // HighGui.imshow("Circle Cropped", dst);
        // HighGui.waitKey(0);

        return dst;

    }

    public static void main(String[] args) throws Exception {
        Mat colorImage = Imgcodecs.imread("C:\\Users\\liting\\Pictures\\20240515000223049.jpg");
        Circle circle = new Circle();
        circle.setCenterX(800);
        circle.setCenterY(300);
        circle.setRadius(100);
        Mat dest = getCircle(colorImage, circle);

        double distance = MinMaxPixel.getColorDistance(dest);

        Rectangle rectangle = new Rectangle();
        rectangle.setLeftTopX(500);
        rectangle.setLeftTopY(200);
        rectangle.setHeight(200);
        rectangle.setWidth(500);

        Mat dest2 = getRect(colorImage, rectangle);
        double distance2 = MinMaxPixel.getColorDistance(dest2);


        System.out.println(distance);
        System.out.println(distance2);


//        ImagePixel entropy=getPixelByCoord("C:\\Users\\liting\\Pictures\\20240515000223049.jpg",321,767);
//
//
//
//
//
//        System.out.println(entropy.toString());
//
//        GrayImagePixel grayImagePixel=getGrayPixelByCoord("C:\\Users\\lit21245\\Pictures\\Buy.jpg",321,767);
//
//
//
//        System.out.println(grayImagePixel.toString());
    }
}
